package com.myhouse.common.utils.myquartz.utils;

import com.myhouse.common.utils.myquartz.action.SchedulerAction;
import com.myhouse.common.utils.myquartz.config.MyQuartzConfig;
import com.myhouse.common.utils.myquartz.entity.JobDetailAndTriggerPair;
import com.myhouse.common.utils.myquartz.factory.JobDetailFactory;
import com.myhouse.common.utils.myquartz.factory.TriggerFactory;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * quartz工具类
 * @version 1.0
 * @author 章瑜亮
 */
@Slf4j
@Component
public class QuartzUtil {

    /**
     * 全局变量
     */
    private static Map<String, JobDetailAndTriggerPair> pairMap =
            new ConcurrentHashMap<>();

    /**
     * 持久化
     */
    private static Map<String, JobDetailAndTriggerPair> permanentMap =
            new ConcurrentHashMap<>();

    /**
     * scheduler
     */
    private static SchedulerAction schedulerAction = new SchedulerAction();


    /**
     * 放入全局变量中缓存
     * @param jobCls 要运行的类
     * @param taskId 任务id（可选）
     * @param config quartz配置类
     * @param params 运行参数
     */
    public QuartzUtil addPair(
            Class<? extends Job> jobCls,
            String taskId,
            MyQuartzConfig config,
            Map<String,Object> params
    ) {
        //jobDetail
        String jobName = jobCls.getSimpleName() + "_job";
        String jobGroupName = jobCls.getSimpleName() + "_jobGroup";
        if (taskId != null && !taskId.isEmpty()) {
            jobName += "_" + taskId;
            jobGroupName += "_" + taskId;
        }
        JobDetail myJobDetail = JobDetailFactory.getInstance(
                jobCls,jobName,jobGroupName,params
        );
        log.info("$$$$$$$$$ start jobName =  "+ jobName + "$$$$$$$$$$");
        //trigger
        String triggerName = jobCls.getSimpleName() + "_trigger";
        String triggerGroupName = jobCls.getSimpleName() + "_triggerGroup";
        if (taskId != null && !taskId.isEmpty()) {
            triggerName += "_" + taskId;
            triggerGroupName += "_" + taskId;
        }
        Trigger myTrigger = TriggerFactory.getInstance(
                jobCls,config,triggerName,triggerGroupName,params
        );
        JobDetailAndTriggerPair pair = new JobDetailAndTriggerPair();
        pair.setJobDetail(myJobDetail).setTriggeer(myTrigger);
        //往执行map中插入元素
        if (pairMap.get(jobName) == null) {
            pairMap.put(jobName, pair);
        }
        //如果为cron模式或者simple模式中重复循环执行，则持久化为true
        String mode = config.getMode();
        String repeatable = config.getRepeatable();
        if (mode.equalsIgnoreCase("cron")
        || repeatable.equalsIgnoreCase("true")) {
            permanentMap.put(jobName,pair);
        }
        return this; //方便链式处理
    }

    /**
     * 暂停任务
     * @param jobCls 任务类
     * @param taskId 任务id
     */
    public synchronized void pause(
            Class<? extends Job> jobCls,
            String taskId
    ) {
        //获取jobName
        String jobName = jobCls.getSimpleName() + "_job";
        if (taskId != null && !taskId.isEmpty()) {
            jobName += "_" + taskId;
        }
        log.info("$$$$$$$$$ pause jobName =  "+ jobName + "$$$$$$$$$$");
        //scheduler暂停任务，通过jobName获取jobDetail和trigger
        if (permanentMap.containsKey(jobName)) {
            JobDetailAndTriggerPair pair = permanentMap.get(jobName);
            schedulerAction.pause(pair);
        }
    }

    /**
     * 重启任务
     * @param jobCls 任务类
     * @param taskId 任务id
     */
    public synchronized void resume(
            Class<? extends Job> jobCls,
            String taskId
    ) {
        //获取jobName
        String jobName = jobCls.getSimpleName() + "_job";
        if (taskId != null && !taskId.isEmpty()) {
            jobName += "_" + taskId;
        }
        log.info("$$$$$$$$$ resume jobName =  "+ jobName + "$$$$$$$$$$");
        //scheduler暂停任务，通过jobName获取jobDetail和trigger
        if (permanentMap.containsKey(jobName)) {
            JobDetailAndTriggerPair pair = permanentMap.get(jobName);
            schedulerAction.resume(pair);
        }
    }

    /**
     * 执行缓存中的任务
     */
    public void executeAll() {
        for(JobDetailAndTriggerPair pair: pairMap.values()) {
            schedulerAction.schedule(pair);
        }
        //执行完毕清空
        pairMap.clear();
        schedulerAction.start();
    }

    /**
     * 执行缓存中的任务
     * @param jobCls 要运行的类
     * @param taskId 任务id
     * @param config quartz配置类
     * @param params 运行参数
     */
    public synchronized void addAndExecute(
            Class<? extends Job> jobCls,
            String taskId,
            MyQuartzConfig config,
            Map<String,Object> params
    ) {
       this.addPair(jobCls, taskId, config, params).executeAll();
    }
}
